package edu.ustb.efws.pipeline.collect.handler;

import edu.ustb.efws.EfwsProperties;
import edu.ustb.efws.pipeline.collect.Collect;
import edu.ustb.efws.pipeline.collect.cache.MaxICacheService;
import edu.ustb.efws.pipeline.domain.Ipt;
import edu.ustb.efws.pipeline.domain.IptLog;
import edu.ustb.efws.pipeline.service.IptLogService;
import edu.ustb.efws.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * ipt设备数据处理
 *
 * @author TS Group
 */
 class IptLogHandler implements PipelineHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(IptLogHandler.class);

    private final IptLogService service;
    private final MaxICacheService maxICacheService;
    private final EfwsProperties properties;

    IptLogHandler(IptLogService service, MaxICacheService maxICacheService, EfwsProperties properties) {
        this.service = service;
        this.maxICacheService = maxICacheService;
        this.properties = properties;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Optional<Object> handle0(Object data) {
        Collect collect = (Collect)data;
        List<Ipt> iPTs = (List<Ipt>)collect.getData();
        if(iPTs == null || iPTs.isEmpty()){
            return Optional.empty();
        }

        iPTs = filterWorkTime(iPTs);
        if(iPTs.isEmpty()){
            return Optional.empty();
        }

        List<IptLog> logs = iPTs.stream().map(this::newIptLog).collect(Collectors.toList());
        service.save(collect.getColTableName(), logs);
        return Optional.of(logs);
    }

    private List<Ipt> filterWorkTime(List<Ipt> logs){
        return logs.stream().filter(e -> {
            LocalDateTime localDateTime = DateUtils.dateToLocalDataTime(e.getTime());
            int minute = localDateTime.getHour() * 60 + localDateTime.getMinute();
            return minute >= properties.getMeterStartMinute() && minute <= properties.getMeterEndMinute();
        }).collect(Collectors.toList());
    }

    private IptLog newIptLog(Ipt t){
        IptLog log = new IptLog();

        log.setDetectorId(t.getDetectorId());
        log.setMonth(DateUtils.dateToMonthNum(t.getTime()));
        log.setI1(t.getI1());
        log.setI2(t.getI2());
        log.setI3(t.getI3());
        log.setMaxI(Math.max(t.getI1(), Math.max(t.getI2(), t.getI3())));
        log.setU1(t.getU1());
        log.setU2(t.getU2());
        log.setU3(t.getU3());
        log.setMaxU(Math.max(t.getU1(), Math.max(t.getU2(), t.getU3())));
        log.setP(t.getP());
        log.setCollectTime(t.getTime());

        updateMaxI(log);

        return log;
    }

    private void updateMaxI(IptLog t){
        maxICacheService.put(t.getDetectorId(), t.getMaxI());
    }
}
